<template>
  <div>
    <el-drawer
      :title="titleData[type]"
      :visible.sync="drawer"
      size="700px"
      :show-close="false"
      @close="handleClose"
    >
      <div class="exportContent">
        <!--      步骤条-->
        <div style="margin-bottom: 10px">
          <el-steps :space="320" :active="stepActive" finish-status="success" process-status="wait" align-center>
            <el-step title="选择要导出的学生"></el-step>
            <el-step title="选择要导出的内容"></el-step>
          </el-steps>
        </div>
        <!--      搜索-->
        <div class="searchBar">
          <el-input
            class="sea_input"
            v-model="searchText"
            :placeholder="stepActive==1? '请输入学生姓名或学号' : '请输入想要检索的目录名'"
            clearable
          >
            <i slot="suffix" class="el-input__icon el-icon-search" v-if="!searchText"></i>
          </el-input>
        </div>
        <!--      内容-->
        <div class="listContent">
          <!--        学生列表-->
          <div v-if="stepActive==1" class="studentList" v-loading="studentLoading">
            <div v-if="showStudentList&&showStudentList.length>0">
              <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange"
                           class="checkAll"
              >全选
              </el-checkbox>
              <el-checkbox-group v-model="checkedStudents" @change="handleCheckedStudentsChange">
                <div :class="checkedStudents.includes(item.studentId)? 'checkBoxContent active':'checkBoxContent' " v-for="(item, index) in showStudentList" :key="index">
                  <el-checkbox  :label="item.studentId"
                                class="block-checkbox"
                  >
                    {{ `${item.studentName}（${item.studentNum}）` }}
                  </el-checkbox>
                </div>
              </el-checkbox-group>
            </div>
            <el-empty :description="`暂无学习的学生`" v-else :image-size="120" class="empty"></el-empty>
          </div>
          <!--        数状结构-->
          <div v-if="stepActive==2" class="courseTreeList" v-loading="treeLoading">
            <div v-if="courseTree&&courseTree.length>0">
<!--              <div class="filter-handle">-->
<!--                <el-checkbox v-model="treeCheckAll" @change="handleTreeCheckAllChange">-->
<!--                  <tooltip width="270" :text="courseInfo.courseName"></tooltip>-->
<!--                </el-checkbox>-->
<!--                <div class="pointer" style="display: flex;align-items: center;" @click="handleChange">-->
<!--                  <div class="icon">-->
<!--                    <i :class="isExpandAll?'el-icon-minus':'el-icon-plus'" @click="isExpandAll=false"></i>-->
<!--                  </div>-->
<!--                  <div style="font-size: 14px;">{{ isExpandAll ? '全部收起' : '全部展开' }}</div>-->
<!--                </div>-->
<!--              </div>-->
              <el-tree
                ref="tree"
                :data="courseTree"
                show-checkbox
                node-key="id"
                default-expand-all
                :default-checked-keys="treeCheckedKeys"
                :props="defaultProps"
                :filter-node-method="filterNode"
                @check="nodeChecked"
              >
                <div slot-scope="{ data}" class="tree-node-wrapper" >
                  <div :style="{ width: `100%`}">
                    <tooltip width="100%" :text="data.name"></tooltip>
                  </div>
                </div>
              </el-tree>
            </div>
            <el-empty :description="`该课程暂无${type == 1 ? '作业' : '考核'}`" v-else :image-size="120" class="empty"></el-empty>
          </div>
        </div>
        <!--      底部按钮-->
        <div class="bottomBtn">
          <div class="item_l" v-if="stepActive==2">注：仅展示有{{ type == 1 ? '作业' : type == 2 ? '考核':'考核或作业' }}的内容</div>
          <div class="item_r">
            <div>已选择{{ checkedStudents.length }}名学生</div>
            <div class="btnItem" @click="prevStep" v-if="stepActive==2">上一步</div>
            <div class="btnItem cancel" @click="handleClose">取 消</div>
            <div class="btnItem" @click="nextStep" v-if="stepActive==1">下一步</div>
            <div class="btnItem" @click="handleConfirm" v-if="stepActive==2&&type!=3">确 定</div>
            <div class="btnItem" @click="handleExport" v-if="stepActive==2&&type==3">导 出</div>
          </div>
        </div>
      </div>
    </el-drawer>
    <!--    导出考核弹窗-->
    <ExportExamDia ref="exportExamDia"></ExportExamDia>
  </div>
</template>

<script>
import ExportExamDia from '@/views/teachIndex/compontents/ExportExamDia.vue'
import { getStudentStudyList } from '@/api/home'
import {
  exportExamTree,
  exportLearningResult,
  exportStuExamPaper,
  getExportLearningResultProgress
} from '@/api/CourseTeach'

export default {
  name: 'exportDrawer',
  components: { ExportExamDia },
  data() {
    return {
      drawer: false,
      // 导出类型1：课后作业，2：考核，3：成果
      type: 1,
      // 课程详情
      courseInfo: {},
      titleData: {
        1: '导出课后作业',
        2: '导出考核',
        3: '导出成果'
      },
      stepActive: 1,
      // 搜索文本
      searchText: '',
      // 学生列表
      studentLoading:false,
      studentList: [
      ],
      showStudentList: [],
      // 学生列表选择
      checkAll: false,
      checkedStudents: [],
      isIndeterminate: null,
      // 课程树状
      treeLoading:false,
      courseTree: [
      ],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 树状选择
      treeCheckedKeys: [],
      // 添加缓存树选择状态
      cachedTreeCheckedKeys: [], // 缓存选中的树节点keys
      treeDataNum: void 0,
      treeCheckAll: false,
      isExpandAll: true,
      // 添加加载状态
      downloadLoading: null,
      downloadProgress: 0, // 添加进度百分比数据
      // 轮询定时器
      pollingTimer: null

    }
  },
  beforeDestroy() {
    // 组件销毁前清理轮询
    this.clearPolling()
    // 添加安全检查
    if (this.downloadLoading && this.downloadLoading.close) {
      this.downloadLoading.close()
    }
  },
  watch: {
    searchText(val) {
      if (this.stepActive == 1) {
        this.handleSearch()
      } else {
        this.$refs.tree.filter(val)
      }
    }
  },
  methods: {
    handleOpen(type, courseInfo) {
      this.type = type
      this.courseInfo = courseInfo
      this.getStudentList()
      this.drawer = true
    },
    // 获取学生列表
    async getStudentList() {
      try{
        this.studentLoading=true
        let res=await getStudentStudyList(this.courseInfo.courseSchedulingId,2)
        if(res.code==200){
          this.studentList=res.data.studentList
          this.showStudentList = this.studentList
        }
      }catch (err){
        console.log(err)
      }finally {
        this.studentLoading=false
      }
    },
    // 获取树状列表
    async getCourseTree() {
      try{
        this.treeLoading=true
        let res=await exportExamTree(this.courseInfo.courseId,this.type==1?6:this.type==2?1:0)
        if(res.code==200){
          this.courseTree=res.data||[]
          this.treeDataNum = this.getAllNodesCount(this.courseTree)
          // 如果有缓存的选择状态，则恢复
          if (this.cachedTreeCheckedKeys.length > 0) {
            this.$nextTick(() => {
              this.treeCheckedKeys = [...this.cachedTreeCheckedKeys]
            })
          }
        }
      }catch (e){
        console.log(e)
      }finally {
        this.treeLoading=false
      }
    },
    // 下一步
    nextStep() {
      if (this.checkedStudents.length == 0) {
        this.$message.warning('请选择要导出的学生')
        return
      }
      this.getCourseTree()
      this.stepActive = 2
      this.searchText = ''
    },
    prevStep(){
      // 保存当前树的选择状态
      if (this.$refs.tree) {
        this.cachedTreeCheckedKeys = this.$refs.tree.getCheckedKeys()
      }

      this.getStudentList()
      this.stepActive = 1
      this.searchText = ''
    },
    // 导出考核或作业
    handleConfirm() {
      // 选中学生数据
      let studentList = this.studentList
        .filter(item => this.checkedStudents.includes(item.studentId))
        .map(item => ({
          studentId: item.studentId,
          studentName: item.studentName,
          studentNum: item.studentNum
        }))
      // 获取的是所有节点Id不包含父节点
      const checkedNodes = this.$refs.tree.getCheckedNodes(true, false)
      const examIdList = checkedNodes.length > 0 ? checkedNodes.map(item => item.examId) : undefined
      if(!examIdList){
        this.$message.warning('请选择要导出的课程环节')
        return
      }
      this.$refs.exportExamDia.handleOpen(this.type, this.courseInfo, studentList, examIdList)
    },
    // 导出学习成果
   async handleExport() {
      // 选中学生数据
      let studentIds=this.checkedStudents.join(',')
      // 获取的是所有节点Id不包含父节点
      const checkedNodes = this.$refs.tree.getCheckedNodes(true, false)
      const indexIdList = checkedNodes.length > 0 ? checkedNodes.map(item => item.id) : []
      let indexIds=indexIdList.join(',')
      if(!indexIds){
        this.$message.warning('请选择要导出的课程环节')
        return
      }
      let data={
        indexIds,
        studentIds,
        courseSchedulingId:this.courseInfo.courseSchedulingId
      }
      console.log(data,'jkjkjkjkjkjkjj')
     let res = await exportLearningResult(data)
     if (res.code == 200) {
       let uuid = res.data
       // 开始轮询查询进度
       this.startPolling(uuid)
     }
    },
    handleClose() {
      this.stepActive = 1
      this.isIndeterminate = null
      this.checkedStudents = []
      this.checkAll = false
      this.searchText = ''
      this.treeCheckedKeys = []
      this.cachedTreeCheckedKeys = [] // 清理缓存
      this.treeDataNum = void 0
      this.treeCheckAll = false
      this.drawer = false
      // 关闭时清理轮询
      this.clearPolling()
    },
    // 学生列表全选
    handleCheckAllChange(val) {
      this.checkedStudents = val ? this.showStudentList.map(item => {
        return item.studentId
      }) : []
      this.isIndeterminate = false
    },
    // 学生列表反选
    handleCheckedStudentsChange(value) {
      let checkedCount = value.length
      this.checkAll = checkedCount === this.showStudentList.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.showStudentList.length
    },
    // 学生列表搜索
    handleSearch() {
      if (this.searchText) {
        this.showStudentList = this.studentList.filter(item => {
          if (item.studentName.includes(this.searchText) || item.studentNum.includes(this.searchText)) {
            return item
          }
        })
      } else {
        this.showStudentList = this.studentList
        this.checkAll = this.checkedStudents.length === this.showStudentList.length
        this.isIndeterminate = this.checkedStudents.length > 0 && this.checkedStudents.length < this.showStudentList.length
      }
    },
    // 获取树状所有节点个数
    getAllNodesCount(treeData) {
      let count = 0
      for (let node of treeData) {
        count++ // 计数当前节点
        if (node.children && node.children.length > 0) {
          count += this.getAllNodesCount(node.children) // 递归计数子节点
        }
      }
      return count
    },
    // 树状检索
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    // 展开树状
    expandAllNodes(node) {
      if (node) {
        node.expanded = true
        if (node.childNodes) {
          node.childNodes.forEach((childNode) => {
            this.expandAllNodes(childNode)
          })
        }
      }
    },
    // 合起树状
    collapseAllNodes(node) {
      if (node) {
        node.expanded = false
        if (node.childNodes) {
          node.childNodes.forEach((childNode) => {
            this.collapseAllNodes(childNode)
          })
        }
      }
    },
    // 树状反选
    nodeChecked(e, n) {
      let arr1 = []
      n.checkedNodes.forEach((e) => {
        if (e.id) {
          arr1.push(e.id)
        }
      })
      if ((this.treeDataNum == arr1.length) && arr1.length > 0) {
        this.treeCheckAll = true
      } else {
        this.treeCheckAll = false
      }
    },
    // 树状全选
    handleTreeCheckAllChange(val) {
      this.$refs.tree.setCheckedNodes(val ? this.courseTree : [])
    },
    // 操作树状展开收起
    handleChange() {
      this.isExpandAll = !this.isExpandAll
      if (this.isExpandAll) {
        this.$nextTick(() => {
          this.expandAllNodes(this.$refs.tree.store.root)
        })
      } else {
        this.$nextTick(() => {
          this.collapseAllNodes(this.$refs.tree.store.root)
        })
      }
    },
    // 开始轮询查询下载进度
    startPolling(uuid) {
      this.downloadLoading = this.$loading({
        lock: true,
        text: `正在导出，请稍后... ${this.downloadProgress}%`,
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      this.clearPolling() // 清理之前的轮询
      // 立即查询一次
      this.pollDownloadProgress(uuid)
      // 设置定时器定期查询
      this.pollingTimer = setInterval(() => {
        this.pollDownloadProgress(uuid)
      }, 5000) // 每5秒查询一次
    },
    // 清理轮询定时器
    clearPolling() {
      if (this.pollingTimer) {
        clearInterval(this.pollingTimer)
        this.pollingTimer = null
      }
    },
    // 轮询查询下载进度
    async pollDownloadProgress(uuid) {
      try {
        let res = await getExportLearningResultProgress(uuid)
        if (res.code == 200) {
          // 更新进度百分比
          if (res.data.progress !== undefined) {
            this.downloadProgress = res.data.progress
            // 更新Loading显示
            if (this.downloadLoading) {
              this.downloadLoading.setText(`正在导出，请稍后... ${this.downloadProgress}%`)
            }
          }
          if (res.data.status === 'SUCCESS') {
            // 下载完成，停止轮询并开始下载文件
            this.clearPolling()
            this.downloadFileWithBlob(res.data.downloadUrl)
            // TODO:确认失败状态字段
          } else if (res.data.status === 'FAILED') {
            // 下载失败，停止轮询并提示错误
            this.clearPolling()
            this.downloadLoading.close()
            this.$message.error('文件导出失败，请重试')
          }
          // 其他状态继续轮询
        }
      } catch (err) {
        console.log(err)
        this.clearPolling()
        this.downloadLoading.close()
        this.$message.error('查询下载进度失败')
      }
    },
    // 使用Blob方式下载文件（可选方案）
    async downloadFileWithBlob(url) {
      try {
        const response = await fetch(url)
        const blob = await response.blob()
        const downloadUrl = window.URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = downloadUrl
        link.download = `【${this.courseInfo.schedulingName}】学习成果-${this.courseInfo.courseName}.zip` // 设置文件名
        link.click()
        window.URL.revokeObjectURL(downloadUrl)
        // 延时关闭弹窗，给用户看到成功提示的时间
      } catch (err) {
        console.error('下载文件失败:', err)
        this.$message.error('文件下载失败')
      }finally {
        setTimeout(() => {
          this.downloadLoading.close()
          this.handleClose()
        }, 1500)
      }
    }
  }
}

</script>

<style scoped lang="scss">
::v-deep .el-drawer__header{
  font-family: PingFangSC, PingFang SC;
  font-weight: 600;
  font-size: 18px;
  color: #333333;
  line-height: 25px;
  padding-bottom: 20px;
  box-sizing: border-box;
  border-bottom: 1px solid #e8e8e8;
  margin-bottom: 16px;
}
::v-deep .el-step__icon {
  width: 32px !important;
  height: 32px !important;
}
::v-deep .el-step.is-horizontal .el-step__line {
  top: 16px !important;
  height: 1px !important;
}
::v-deep .el-step__line-inner{
  border-width: 0.5px !important;
  border-color: #28B28B !important;
}
  ::v-deep .el-step__title {
  font-size: 14px !important;
  font-weight: 400;
}
::v-deep .el-step__icon.is-text {
  background: #f0f0f0;
  border: 0;
  color: rgba(0,0,0,0.45);
}
  ::v-deep .el-step__head.is-success .el-step__icon{
  background:#ebfaf8;
  border: 0;
  color: #28b28b;
}
::v-deep .el-step__title.is-success{
  font-family: PingFangSC, PingFang SC;
  color: #28B28B;
}
//树状
::v-deep .el-tree-node.is-checked{
  background: #EBFAF8;
}
.exportContent {
  width: 100%;
  height: 100%;
  padding: 0 32px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;

  .searchBar {
    width: 100%;
    display: flex;
    align-items: center;
    .sea_input{
      width: 240px;

    }
    ::v-deep .el-input__inner {
      background: rgba(0,0,0,0.04);
      border-radius: 6px;
      border: 0;
    }
  }

  .listContent {
    width: 100%;
    flex: 1;
    border-radius: 8px;
    border: 1px solid rgba(0,0,0,0.15);
    margin: 12px 0 24px;
    padding: 24px 10px;
    box-sizing: border-box;
    overflow-y: auto;

    .studentList {
      width: 100%;
      height: 100%;
      position: relative;
      .empty {
        transform: translate(-50%, -50%);
        position: absolute;
        top: 50%;
        left: 50%;
      }
      .checkAll {
        margin-bottom: 5px;
        margin-left: 10px;
      }

      .block-checkbox {
        display: block;
      }
      .checkBoxContent{
        height: 32px;
        display: flex;
        align-items: center;
        padding: 0 10px;
        box-sizing: border-box;
        margin-bottom: 5px;

      }
      .checkBoxContent.active{
        background: rgba(5,192,173,0.08);
      }

    }

    .courseTreeList {
      width: 100%;
      height: 100%;
      position: relative;
      .tree-node-wrapper {
        width: 100%;
        overflow: hidden;
      }

      .filter-handle {
        display: flex;
        align-items: center;
        justify-content: space-between;

        .pointer {
          cursor: pointer;
        }

        .icon {
          width: 14px;
          height: 14px;
          line-height: 14px;
          border: 1px solid #ccc;
          text-align: center;
          margin-right: 5px;
          color: #28b28b;
          font-size: 12px;
        }
      }

      .empty {
        transform: translate(-50%, -50%);
        position: absolute;
        top: 50%;
        left: 50%;
      }
    }
  }

  .bottomBtn {
    width: 100%;
    display: flex;
    align-items: center;
    margin-bottom: 37px;
    font-size: 14px;

    .item_l {
      flex-shrink: 0;
      font-family: PingFangSC, PingFang SC;
      font-weight: 400;
      font-size: 16px;
      color: #F7B500;
    }

    .item_r {
      flex: 1;
      display: flex;
      justify-content: flex-end;
      align-items: center;
      font-size: 16px;
      .btnItem {
        width: 80px;
        height: 38px;
        line-height: 38px;
        text-align: center;
        color: #fff;
        background: #28b28b;
        font-size: 14px;
        margin-left: 10px;
        border-radius: 8px;
      }

      .cancel.btnItem {
        background: #fff;
        color: #000;
        border: 1px solid #bbbbbb;
      }
    }
  }
}
</style>
